package com.xxgg.start.controller.system;


import cn.dev33.satoken.annotation.SaCheckPermission;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xxgg.common.annotation.OpenLog;
import com.xxgg.common.utils.poi.ExcelUtil;
import com.xxgg.system.model.po.Logs;
import com.xxgg.common.core.model.vo.SelectBoxVo;
import com.xxgg.system.service.LogsService;
import com.xxgg.common.enums.BusinessType;
import com.xxgg.common.result.ResultCodeEnum;
import com.xxgg.common.result.ResultJSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.util.List;

/**
 * <p>
 * 系统操作日志 前端控制器
 * </p>
 *
 * @author 先谢郭嘉
 * @since 2022-07-14 02:04:08
 */
@Validated
@Slf4j
@Api(tags = "操作日志管理")
@RestController
@RequestMapping("/system/logs")
public class LogsController {
    @Resource
    private LogsService logsService;

    @ApiOperation(value = "获取所有接口返回状态码", httpMethod = "GET")
    @GetMapping("/getCodeList")
    public ResultJSON<List<SelectBoxVo>> getCodeList(){
        return ResultJSON.success(ResultCodeEnum.getAllCode());
    }

    @ApiOperation(value = "获取所有业务操作类型", httpMethod = "GET")
    @GetMapping("/getBusinessTypeList")
    public ResultJSON<List<SelectBoxVo>> getBusinessTypeList(){
        return ResultJSON.success(BusinessType.getAllBusinessType());
    }


    @SaCheckPermission("logs:page")
    @OpenLog(module = "操作日志管理", name = "分页模糊查询日志", businessType = BusinessType.SELECT)
    @ApiOperation(value = "分页模糊查询日志", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "每页数量", name = "size", required = true),
            @ApiImplicitParam(value = "页码", name = "current", required = true),
            @ApiImplicitParam(value = "操作模块", name = "module", required = false),
            @ApiImplicitParam(value = "业务操作类型", name = "businessType", required = false),
            @ApiImplicitParam(value = "请求状态",name = "requestCode",required = false),
            @ApiImplicitParam(value = "请求方式",name = "requestMethod",required = false),
            @ApiImplicitParam(value = "搜索关键字",name = "search",required = false)
    })
    @GetMapping("/page")
    public ResultJSON<Page<Logs>> logsPage(Integer size, Integer current, String requestCode, String search,
                                           String requestMethod, String module, String businessType){
        Page<Logs> logsPage = logsService.lambdaQuery()
                .eq(StringUtils.isNotBlank(module), Logs::getModule, module)
                .eq(StringUtils.isNotBlank(businessType), Logs::getBusinessType, businessType)
                .eq(StringUtils.isNotBlank(requestCode), Logs::getRequestCode, requestCode)
                .eq(StringUtils.isNotBlank(requestMethod), Logs::getRequestMethod, requestMethod)
                .and(StringUtils.isNotBlank(search), item -> item
                        .like(Logs::getIp, search).or()
                        .like(Logs::getUrl, search).or()
                        .like(Logs::getModule, search).or()
                        .like(Logs::getBusinessType, search).or()
                        .like(Logs::getMethodNameZh, search).or()
                        .like(Logs::getMethodNameEn, search).or()
                        .like(Logs::getUserName, search).or()
                        .like(Logs::getLocation, search))
                .orderByDesc(Logs::getLogTime)
                .page(new Page<>(current, size));
        return ResultJSON.success(logsPage).message("分页模糊查询日志");
    }

    @ApiOperation(value = "获取日志详情", httpMethod = "GET")
    @ApiImplicitParam(value = "日志id",name = "logId",required = true)
    @GetMapping("/getLog")
    public ResultJSON<Logs> getLog(String logId){
        return ResultJSON.success(logsService.getById(logId));
    }

    @SaCheckPermission("logs:delete")
    @OpenLog(module = "操作日志管理", name = "批量删除日志", businessType = BusinessType.DELETE)
    @ApiOperation(value = "批量删除日志", httpMethod = "DELETE")
    @ApiImplicitParam(value = "日志id集合",name = "logIdList",required = true)
    @DeleteMapping("/delete")
    public ResultJSON<Boolean> deleteLog(@NotNull(message = "日志id不能为空") @RequestParam("logIdList") List<String> logIdList){
        return logsService.removeBatchByIds(logIdList) ? ResultJSON.success() : ResultJSON.error();
    }

    @SaCheckPermission("logs:export")
    @OpenLog(module = "操作日志管理", name = "导出日志", businessType = BusinessType.EXPORT)
    @ApiOperation(value = "导出日志", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "导出的文件名称", name = "fileName", required = false),
            @ApiImplicitParam(value = "操作模块", name = "module", required = false),
            @ApiImplicitParam(value = "业务操作类型", name = "businessType", required = false),
            @ApiImplicitParam(value = "请求状态",name = "requestCode",required = false),
            @ApiImplicitParam(value = "请求方式",name = "requestMethod",required = false),
            @ApiImplicitParam(value = "开始时间", name = "startTime", required = false),
            @ApiImplicitParam(value = "结束时间", name = "endTime", required = false),
    })
    @GetMapping(value = "/export", produces = "application/octet-stream")
    public void export(String fileName, String module, String businessType, String requestCode, String requestMethod,
                       String startTime, String endTime, HttpServletResponse response){
        List<Logs> logsList = logsService.lambdaQuery()
                .eq(StringUtils.isNotBlank(module), Logs::getModule, module)
                .eq(StringUtils.isNotBlank(businessType), Logs::getBusinessType, businessType)
                .eq(StringUtils.isNotBlank(requestCode), Logs::getRequestCode, requestCode)
                .eq(StringUtils.isNotBlank(requestMethod), Logs::getRequestMethod, requestMethod)
                .between(StringUtils.isNotBlank(startTime) || StringUtils.isNotBlank(endTime),
                        Logs::getLogTime, startTime, endTime)
                .orderByDesc(Logs::getLogTime)
                .list();
        if(StringUtils.isEmpty(fileName)) fileName = startTime + "到" + endTime + "系统日志";

        ExcelUtil.exportExcel(logsList, fileName, Logs.class, response);
    }
}
